<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>铺位编辑 - {{ room_number }}号监室</title>
    <style>
        :root {
            --primary-color: #2c3e50;
            --secondary-color: #3498db;
            --accent-color: #8bc34a;
            --background: #f5f7fa;
            --card-bg: #ffffff;
            --border-color: #e1e4e8;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            margin: 0;
            padding: 20px;
            min-height: 100vh;
            background: var(--background);
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background: var(--card-bg);
            border-radius: 10px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
        }

        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 15px;
            border-bottom: 1px solid var(--border-color);
        }

        .title {
            font-size: 1.8rem;
            color: var(--primary-color);
            font-weight: 600;
        }

        .room-info {
            background: #e3f2fd;
            padding: 8px 15px;
            border-radius: 20px;
            font-size: 1rem;
            color: #1976d2;
        }

        .bed-container {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin-bottom: 30px;
            min-height: 200px;
            position: relative;
            width: 100%;
        }
        
        .bed-card {
            flex: 0 0 calc(25% - 8px);
            background: white;
            border-radius: 12px;
            padding: 15px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            border: 1px solid #e0e0e0;
            cursor: grab;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            position: relative;
            user-select: none;
            touch-action: none;
            animation: fadeInUp 0.5s ease-out;
        }
        
        @media (max-width: 1200px) { .bed-card { flex: 0 0 calc(33.333% - 10px); } }
        @media (max-width: 992px) { .bed-card { flex: 0 0 calc(50% - 10px); } }
        @media (max-width: 768px) { .bed-card { flex: 0 0 100%; } }

        .bed-card:active { cursor: grabbing; }
        .bed-card:hover { transform: translateY(-2px); box-shadow: 0 8px 25px rgba(0,0,0,0.15); }
        .bed-card.dragging {
            cursor: grabbing;
            transform: rotate(5deg) scale(1.05);
            box-shadow: 0 15px 35px rgba(0,0,0,0.3);
            z-index: 1000;
            opacity: 0.9;
            transition: none;
        }
        .bed-card.drag-over {
            transform: scale(1.02);
            box-shadow: 0 8px 25px rgba(52, 152, 219, 0.3);
            border-color: #3498db;
        }

        .bed-number {
            font-weight: bold;
            color: var(--primary-color);
            margin-bottom: 8px;
            font-size: 1.1rem;
        }

        .bed-person {
            display: flex;
            align-items: center;
            margin-bottom: 5px;
        }

        .person-name {
            margin-left: 10px;
            font-size: 1rem;
        }

        .join-date {
            font-size: 0.8rem;
            color: #666;
            margin-top: 5px;
        }

        .empty-bed {
            background: #f5f5f5;
            color: #999;
            font-style: italic;
            display: flex;
            align-items: center;
            justify-content: center;
            min-height: 100px;
        }

        .drag-placeholder {
            background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
            border: 2px dashed #3498db;
            border-radius: 12px;
            opacity: 0.7;
            transition: all 0.3s ease;
            position: relative;
            animation: pulse 1.5s ease-in-out infinite;
            min-height: 120px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 0.9rem;
            color: #3498db;
            font-weight: 500;
            height: 120px;
            width: 100%;
            margin-bottom: 15px;
        }

        .drag-placeholder::before {
            content: '📥 拖拽到此处';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            text-align: center;
            line-height: 1.2;
        }

        .insert-indicator {
            position: absolute;
            width: 4px;
            height: 120px;
            background: linear-gradient(180deg, #3498db, #2ecc71);
            border-radius: 2px;
            opacity: 0.8;
            z-index: 1001;
            pointer-events: none;
            transition: all 0.3s ease;
            box-shadow: 0 0 10px rgba(52, 152, 219, 0.5);
        }

        .drop-success-tip {
            position: fixed;
            top: 20px;
            right: 20px;
            background: #2ecc71;
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            font-size: 14px;
            z-index: 10000;
            animation: slideInRight 0.3s ease;
            box-shadow: 0 4px 12px rgba(46, 204, 113, 0.3);
        }

        .reason-input {
            margin: 20px 0;
            padding: 20px;
            background: #f8f9fa;
            border-radius: 10px;
            border: 1px solid #e9ecef;
        }

        .reason-input h3 {
            margin-bottom: 15px;
            color: var(--primary-color);
        }

        .reason-input textarea {
            width: 100%;
            padding: 15px;
            border: 2px solid #e9ecef;
            border-radius: 8px;
            min-height: 100px;
            font-size: 14px;
            transition: border-color 0.3s ease;
            resize: vertical;
        }

        .reason-input textarea:focus {
            outline: none;
            border-color: #3498db;
            box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
        }

        .actions {
            display: flex;
            justify-content: flex-end;
            gap: 15px;
            margin-top: 30px;
        }

        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            font-size: 1rem;
            cursor: pointer;
            transition: all 0.2s;
        }

        .btn-save {
            background: #2ecc71;
            color: white;
        }

        .btn-save:hover { background: #27ae60; }

        .btn-cancel {
            background: #e74c3c;
            color: white;
        }

        .btn-cancel:hover { background: #c0392b; }

        @keyframes fadeInUp {
            from { opacity: 0; transform: translateY(20px); }
            to { opacity: 1; transform: translateY(0); }
        }

        @keyframes pulse {
            0%, 100% { opacity: 0.7; transform: scale(1); }
            50% { opacity: 1; transform: scale(1.02); }
        }

        @keyframes slideInRight {
            from { opacity: 0; transform: translateX(100%); }
            to { opacity: 1; transform: translateX(0); }
        }

        @media (hover: none) and (pointer: coarse) {
            .bed-card { cursor: default; }
            .bed-card:active { cursor: default; }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1 class="title">{{ room_number }}号监室 - 铺位编辑</h1>
            <div class="room-info">总人数: {{ total }}人</div>
        </div>

        <div class="bed-container" id="bedContainer">
            <div class="drag-hint" style="width: 100%; text-align: center; color: #666; margin-bottom: 20px; font-size: 14px;">
                💡 拖拽卡片可以调整铺位顺序
            </div>
            {% for bed in beds %}
            <div class="bed-card" data-bed-id="{{ bed.position }}" {% if bed.person %}data-person-id="{{ bed.person.id }}" data-fxdj="{{ bed.person.FXDJ }}" data-bhlx="{{ bed.person.BHLX }}"{% endif %}>
                <div class="bed-number">铺位 {{ bed.position }}</div>
                {% if bed.person %}
                <div class="bed-person">
                    <div class="person-name">{{ bed.person.name }}</div>
                </div>
                <div class="join-date">入所日期: {{ bed.person.join_date }}</div>
                {% else %}
                <div class="empty-bed">空位</div>
                {% endif %}
            </div>
            {% endfor %}
        </div>

        <div class="reason-input">
            <h3>变动理由</h3>
            <textarea id="changeReason" placeholder="请输入铺位调整的理由（必填）"></textarea>
        </div>
        
        <div class="actions">
            <button class="btn btn-cancel" onclick="window.history.back()">取消</button>
            <button class="btn btn-save" id="saveBtn">保存修改</button>
        </div>
    </div>

    <script>
        class BedDragManager {
            constructor(container) {
                this.container = container;
                this.draggedItem = null;
                this.draggedIndex = -1;
                this.placeholder = null;
                this.isDragging = false;
                this.startY = 0;
                this.startX = 0;
                this.currentY = 0;
                this.currentX = 0;
                this.isTouchDevice = 'ontouchstart' in window;
                this.touchStartTimeout = null;
                
                this.init();
            }

            init() {
                this.createPlaceholder();
                if (this.isTouchDevice) {
                    this.setupTouchEvents();
                } else {
                    this.setupMouseEvents();
                }
            }

            createPlaceholder() {
                this.placeholder = document.createElement('div');
                this.placeholder.className = 'drag-placeholder';
            }

            setupTouchEvents() {
                const cards = this.container.querySelectorAll('.bed-card');
                cards.forEach(card => {
                    card.addEventListener('touchstart', this.handleTouchStart.bind(this), { passive: false });
                    card.addEventListener('touchmove', this.handleTouchMove.bind(this), { passive: false });
                    card.addEventListener('touchend', this.handleTouchEnd.bind(this), { passive: false });
                });
                
                this.container.addEventListener('touchmove', (e) => {
                    if (this.isDragging) e.preventDefault();
                }, { passive: false });
            }

            setupMouseEvents() {
                const cards = this.container.querySelectorAll('.bed-card');
                cards.forEach(card => {
                    card.addEventListener('mousedown', this.handleMouseDown.bind(this));
                });
                
                document.addEventListener('mousemove', this.handleMouseMove.bind(this));
                document.addEventListener('mouseup', this.handleMouseUp.bind(this));
            }

            handleTouchStart(e) {
                const card = e.target.closest('.bed-card');
                if (!card) return;
                
                e.preventDefault();
                this.touchStartTimeout = setTimeout(() => {
                    this.startDrag(card, e.touches[0].clientY, e.touches[0].clientX);
                }, 150);
            }

            handleTouchMove(e) {
                if (!this.isDragging) return;
                e.preventDefault();
                this.updateDragPosition(e.touches[0].clientY, e.touches[0].clientX);
                this.updatePlaceholderPosition();
            }

            handleTouchEnd(e) {
                if (this.touchStartTimeout) {
                    clearTimeout(this.touchStartTimeout);
                    this.touchStartTimeout = null;
                }
                if (!this.isDragging) return;
                e.preventDefault();
                this.finalizeDrop();
            }

            handleMouseDown(e) {
                const card = e.target.closest('.bed-card');
                if (!card) return;
                e.preventDefault();
                this.startDrag(card, e.clientY, e.clientX);
            }

            handleMouseMove(e) {
                if (!this.isDragging) return;
                e.preventDefault();
                this.updateDragPosition(e.clientY, e.clientX);
                this.updatePlaceholderPosition();
            }

            handleMouseUp(e) {
                if (!this.isDragging) return;
                e.preventDefault();
                this.finalizeDrop();
            }

            startDrag(item, clientY, clientX) {
                this.draggedItem = item;
                this.draggedIndex = this.getCardIndex(item);
                this.isDragging = true;
                this.startY = clientY;
                this.startX = clientX;
                this.currentY = clientY;
                this.currentX = clientX;
                
                setTimeout(() => {
                    item.classList.add('dragging');
                    this.insertPlaceholder();
                }, 0);
            }

            endDrag() {
                if (!this.isDragging) return;
                
                this.isDragging = false;
                
                if (this.touchStartTimeout) {
                    clearTimeout(this.touchStartTimeout);
                    this.touchStartTimeout = null;
                }
                
                if (this.draggedItem) {
                    this.draggedItem.classList.remove('dragging');
                    this.draggedItem.style.transform = '';
                }
                
                this.removePlaceholder();
                this.updateBedPositions();
                
                this.draggedItem = null;
                this.draggedIndex = -1;
            }

            updateDragPosition(clientY, clientX) {
                this.currentY = clientY;
                this.currentX = clientX;
            }

            updatePlaceholderPosition() {
                if (!this.isDragging || !this.placeholder) return;
                
                const targetIndex = this.calculateInsertPosition(this.currentX, this.currentY);
                this.movePlaceholderToIndex(targetIndex);
            }

            calculateInsertPosition(clientX, clientY) {
                const cards = [...this.container.querySelectorAll('.bed-card:not(.dragging)')];
                if (cards.length === 0) return 0;
                
                const containerStyle = window.getComputedStyle(this.container);
                const flexWrap = containerStyle.flexWrap;
                
                if (flexWrap === 'nowrap') {
                    return this.findHorizontalPosition(cards, clientX);
                } else {
                    return this.findMultiRowPosition(cards, clientX, clientY);
                }
            }
            
            findHorizontalPosition(cards, clientX) {
                for (let i = 0; i < cards.length; i++) {
                    const rect = cards[i].getBoundingClientRect();
                    if (clientX < rect.left + rect.width / 2) return i;
                }
                return cards.length;
            }
            
            findMultiRowPosition(cards, clientX, clientY) {
                const positionMap = cards.map((card, index) => {
                    const rect = card.getBoundingClientRect();
                    return { index, card, rect, centerX: rect.left + rect.width / 2, top: rect.top, bottom: rect.bottom };
                });
                
                const rows = this.groupIntoRows(positionMap);
                const targetRow = this.findTargetRow(rows, clientY);
                
                if (!targetRow) {
                    return clientY < rows[0]?.[0]?.top ? 0 : cards.length;
                }
                
                return this.findPositionInRow(targetRow, clientX, cards);
            }
            
            groupIntoRows(positionMap) {
                if (positionMap.length === 0) return [];
                
                const rows = [];
                let currentRow = [];
                let lastTop = -1;
                const threshold = 20;
                
                positionMap.sort((a, b) => a.top - b.top);
                
                for (const item of positionMap) {
                    if (lastTop === -1 || Math.abs(item.top - lastTop) <= threshold) {
                        currentRow.push(item);
                    } else {
                        if (currentRow.length > 0) {
                            currentRow.sort((a, b) => a.rect.left - b.rect.left);
                            rows.push([...currentRow]);
                        }
                        currentRow = [item];
                    }
                    lastTop = item.top;
                }
                
                if (currentRow.length > 0) {
                    currentRow.sort((a, b) => a.rect.left - b.rect.left);
                    rows.push(currentRow);
                }
                
                return rows;
            }
            
            findTargetRow(rows, clientY) {
                for (const row of rows) {
                    if (clientY >= row[0].top && clientY <= row[0].bottom) {
                        return row;
                    }
                }
                return null;
            }
            
            findPositionInRow(row, clientX, allCards) {
                const firstCardIndex = allCards.indexOf(row[0].card);
                
                for (let i = 0; i < row.length; i++) {
                    if (clientX < row[i].centerX) {
                        return firstCardIndex + i;
                    }
                }
                
                return firstCardIndex + row.length;
            }

            movePlaceholderToIndex(index) {
                if (!this.placeholder) return;
                
                const cards = [...this.container.querySelectorAll('.bed-card:not(.dragging)')];
                
                if (this.placeholder.parentNode) {
                    this.placeholder.parentNode.removeChild(this.placeholder);
                }
                
                if (index === 0) {
                    this.container.insertBefore(this.placeholder, cards[0]);
                } else if (index >= cards.length) {
                    this.container.appendChild(this.placeholder);
                } else {
                    this.container.insertBefore(this.placeholder, cards[index]);
                }
                
                this.showInsertIndicator(index);
            }
            
            showInsertIndicator(index) {
                const existing = document.querySelector('.insert-indicator');
                if (existing) existing.remove();
                
                const indicator = document.createElement('div');
                indicator.className = 'insert-indicator';
                
                const cards = [...this.container.querySelectorAll('.bed-card:not(.dragging)')];
                let left, top;
                
                if (index === 0 && cards.length > 0) {
                    const rect = cards[0].getBoundingClientRect();
                    left = rect.left - 8;
                    top = rect.top;
                } else if (index >= cards.length) {
                    const rect = cards[cards.length - 1].getBoundingClientRect();
                    left = rect.right + 4;
                    top = rect.top;
                } else {
                    const rect = cards[index].getBoundingClientRect();
                    left = rect.left - 8;
                    top = rect.top;
                }
                
                indicator.style.left = left + 'px';
                indicator.style.top = top + 'px';
                this.container.appendChild(indicator);
                
                setTimeout(() => {
                    if (indicator.parentNode) indicator.remove();
                }, 3000);
            }

            insertPlaceholder() {
                if (this.placeholder && this.draggedItem) {
                    this.container.insertBefore(this.placeholder, this.draggedItem);
                }
            }

            removePlaceholder() {
                if (this.placeholder && this.placeholder.parentNode) {
                    this.placeholder.parentNode.removeChild(this.placeholder);
                }
            }

            finalizeDrop() {
                if (!this.isDragging || !this.draggedItem || !this.placeholder) return;
                
                const targetIndex = this.calculateInsertPosition(this.currentX, this.currentY);
                const cards = [...this.container.querySelectorAll('.bed-card:not(.dragging)')];
                
                let insertIndex = targetIndex;
                if (this.draggedIndex < targetIndex) insertIndex--;
                
                insertIndex = Math.max(0, Math.min(insertIndex, cards.length));
                
                if (insertIndex === this.draggedIndex) {
                    this.endDrag();
                    return;
                }
                
                try {
                    if (insertIndex === 0) {
                        this.container.insertBefore(this.draggedItem, cards[0]);
                    } else if (insertIndex >= cards.length) {
                        this.container.appendChild(this.draggedItem);
                    } else {
                        this.container.insertBefore(this.draggedItem, cards[insertIndex]);
                    }
                    
                    this.showDropSuccess(insertIndex);
                    
                } catch (error) {
                    console.error('移动卡片时发生错误:', error);
                }
                
                this.endDrag();
            }
            
            showDropSuccess(insertIndex) {
                const successTip = document.createElement('div');
                successTip.className = 'drop-success-tip';
                successTip.textContent = `已移动到第 ${insertIndex + 1} 个位置`;
                document.body.appendChild(successTip);
                
                setTimeout(() => {
                    if (successTip.parentNode) successTip.remove();
                }, 3000);
            }

            getCardIndex(card) {
                const cards = [...this.container.querySelectorAll('.bed-card')];
                return cards.indexOf(card);
            }

            updateBedPositions() {
                const cards = [...this.container.querySelectorAll('.bed-card')];
                cards.forEach((card, index) => {
                    const bedNumber = card.querySelector('.bed-number');
                    if (bedNumber) {
                        bedNumber.textContent = `铺位 ${index + 1}`;
                        card.dataset.bedId = index + 1;
                    }
                });
            }
        }

        document.addEventListener('DOMContentLoaded', function() {
            const bedContainer = document.getElementById('bedContainer');
            const dragManager = new BedDragManager(bedContainer);

            // 记录原始位置
            const originalPositions = {};
            const initialBeds = Array.from(document.querySelectorAll('.bed-card'));
            initialBeds.forEach((bed, index) => {
                const personId = bed.dataset.personId;
                if (personId) {
                    originalPositions[personId] = index + 1;
                }
            });

            // 保存按钮事件
            document.getElementById('saveBtn').addEventListener('click', function() {
                const changeReason = document.getElementById('changeReason').value.trim();
                if (!changeReason) {
                    alert('请填写变动理由');
                    return;
                }

                const beds = Array.from(document.querySelectorAll('.bed-card'));
                const bedData = beds.map((bed, index) => {
                    const personElement = bed.querySelector('.person-name');
                    const joinDateElement = bed.querySelector('.join-date');
                    const personId = bed.dataset.personId;
                    
                    let joinDate = '';
                    if (joinDateElement) {
                        const rawText = joinDateElement.textContent.trim();
                        joinDate = rawText.match(/\d{4}-\d{2}-\d{2}/)?.[0] || '';
                    }
                    
                    // 获取原始位置的人员信息，包括FXDJ和BHLX字段
                    const originalPerson = initialBeds.find(b => b.dataset.personId === personId);
                    let fxdj = 0, bhlx = 0;
                    if (originalPerson) {
                        // 从原始数据中获取FXDJ和BHLX字段
                        const originalIndex = Array.from(initialBeds).indexOf(originalPerson);
                        if (originalIndex >= 0 && originalPositions[personId]) {
                            const originalBed = initialBeds[originalIndex];
                            // 这里需要从原始数据中获取FXDJ和BHLX，但由于前端数据限制，我们假设这些值在页面加载时已存在
                            // 在实际实现中，这些值应该从后端传递到前端
                            fxdj = originalBed.dataset.fxdj || 0;
                            bhlx = originalBed.dataset.bhlx || 0;
                        }
                    }
                    
                    return personElement ? {
                        person_id: personId,
                        person_name: personElement.textContent.trim(),
                        join_date: joinDate,
                        FXDJ: fxdj,
                        BHLX: bhlx,
                        original_position: originalPositions[personId],
                        new_position: index + 1
                    } : null;
                }).filter(item => item !== null);

                // 生成变动说明
                const generateChangeDescription = (bedData) => {
                    const changedBeds = bedData.filter(item => item.original_position !== item.new_position);
                    
                    if (changedBeds.length === 0) return '无铺位调整';
                    if (changedBeds.length === 1) {
                        const item = changedBeds[0];
                        return `${item.person_name}从${item.original_position}铺位调整到${item.new_position}铺位`;
                    }
                    
                    const insertions = [];
                    const sortedChanges = [...changedBeds].sort((a, b) => a.new_position - b.new_position);
                    
                    sortedChanges.forEach(change => {
                        const { person_name, original_position, new_position } = change;
                        if (new_position < original_position || Math.abs(new_position - original_position) > 1) {
                            insertions.push(`${person_name}插入到${new_position}铺位`);
                        }
                    });
                    
                    return insertions.length > 0 ? insertions.join('；') : 
                        changedBeds.map(item => `${item.person_name}从${item.original_position}铺位调整到${item.new_position}铺位`).join('；');
                };

                const changeDescription = generateChangeDescription(bedData);

                // 发送数据到后端
                fetch('/save_bed_order', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        room_number: '{{ room_number }}',
                        user_id: '{{ user_id }}',
                        operation_time: new Date().toISOString(),
                        change_description: changeDescription,
                        change_reason: changeReason,
                        beds: bedData
                    })
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        alert('铺位顺序保存成功');
                        window.location.href = `/room/{{ room_number }}`;
                    } else {
                        alert('保存失败: ' + data.message);
                    }
                })
                .catch(error => {
                    console.error('Error:', error);
                    alert('保存时发生错误');
                });
            });
        });
    </script>
</body>
</html>